﻿using DataSyncCom;
using DataSyncCommon;
using Newtonsoft.Json;
using Quartz;
using SqlSugar;
using SupDataSync.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleSub
{

    public enum customers
    {
        /// <summary>
        /// 四川
        /// </summary>
        sc = 20510002,
        /// <summary>
        /// 甘肃
        /// </summary>
        gs = 12620203,
        /// <summary>
        /// 贵州
        /// </summary>
        gz = 20520001
    }
    /// <summary>
    /// 1.查询标识为ADD_TYPE 0的业务数据，转换成云数据结构  0：默认新增值，1：已经上传到云端
    /// 2.调用接口上传数据
    /// 3.收到结果
    /// 4.将执行结果写入日志
    /// </summary>
    public class UpData : IJob
    {

        public Task Execute(IJobExecutionContext context)
        {
            Updata();
            log($"执行上传业务数据任务结束{DateTime.Now}");
            return SysConfig.CompletedTask;
        }
        private string CustomerCode { get; set; }
        private DataTable DataSource { get; set; }

        public void Updata()
        {
            var custcds = new List<ba_customer>();
            using (var db = DbHelperMySql.GetSqlSugarDb())
            {
                custcds = db.Queryable<ba_customer>().ToList();
            }
            log($"count  {custcds.Count}");
            var i = 0;
            var str = "";
            foreach (var item in custcds)
            {
                //if (item.customercode == ((int)customers.gs).ToString())
                //{
                SyncBaseData("order_no", item.customercode, DateTime.Now.Date.AddDays(-30));
                SyncBaseData("order_manage", item.customercode, DateTime.Now.Date.AddDays(-30));
                SyncBaseData("order_manage_list", item.customercode, DateTime.Now.Date.AddDays(-30));
                SyncBaseData("pp_big_lab_sup", item.customercode, DateTime.Now.Date.AddDays(-30));
                SyncBaseData("pp_lab_lst_sup", item.customercode, DateTime.Now.Date.AddDays(-30));
                var log1= $"执行上传同步数据{DateTime.Now}完成客户编码{item.customercode} {i.ToString()}";
                log(log1);
                str += log1;
                i++;
                //}
            }
            //var zxlog = LogHelper.InDbLog(new DataSyncCommon.Model.ba_sup_log()
            //{
            //    NOTE = str,
            //    SYS_CODE = "down",
            //    TenantId = SysConfig.TenantId
            //});
        }

        /// <summary>
        /// 同步所有表
        /// </summary>
        /// <param name="customercd"></param>
        private void SyncBaseDataAll(string customercd, DateTime startdate)
        {
            try
            {
                var model = new SyncBusinessModel();
                model.CustomerCode = customercd;
                model.TenantId = SysConfig.TenantId;
                var startDate = startdate;

                //获取本地基础表数据
                using (var db = DbHelperMySql.GetSqlSugarDb())
                {

                    model.OrderList = db.Queryable<order_no>()
                        .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd && p.ORDER_DATE >= startDate)
                        .OrderBy(p => p.ORDER_DATE)
                        .ToList();

                    model.OrderManageList = db.Queryable<order_manage>()
                        .Where(b => b.ADD_TYPE == 0 && b.CUSTOMERCODE == customercd && b.DELIVERY_DATE >= startDate)
                        .OrderBy(p => p.DELIVERY_DATE)
                        .ToList();

                    model.OrderManageDetailList = db.Queryable<order_manage_list, order_manage>((l, m) => new object[]{
                            JoinType.Left, l.ORDER_ID == m.ORDER_ID })
                        .Where((l, m) => l.ADD_TYPE == 0 && m.CUSTOMERCODE == customercd && l.SCAN_TIME >= startDate)
                        .OrderBy((l, m) => l.SCAN_TIME)
                        .Select((l, m) => l)
                        .ToList();

                    model.BigBarcodeList = db.Queryable<pp_big_lab_sup>()
                        .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd && p.CREATE_DT >= startDate)
                        .OrderBy(p => p.CREATE_DT)
                        .ToList();

                    //大量数据
                    model.SmallBarcodeList = db.Queryable<pp_lab_lst_sup>()
                     .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd && p.CREATE_DT >= startDate)
                     .OrderBy(p => p.CREATE_DT)
                     .ToList(); model.SmallBarcodeList = db.Queryable<pp_lab_lst_sup>()
                      .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd && p.CREATE_DT >= startDate)
                      .OrderBy(p => p.CREATE_DT)
                      .ToList();

                }

                var url = SysConfig.SyncBusinessApiUrl;
                var reqjson = JsonConvert.SerializeObject(model);
                var responseStr = HttpHelper.WebRequestApi(url, reqjson, "POST");
                var syncResultList = JsonConvert.DeserializeObject<List<SyncResultModel>>(responseStr);
                DataSet ds = null;
                string sql = @"update `order_no` set `ADD_TYPE`= 1 where `ADD_TYPE` = 0;
update `order_manage` set `ADD_TYPE`= 1 where `ADD_TYPE` = 0;
update `order_manage_list` set `ADD_TYPE`= 1 where `ADD_TYPE` = 0;
update `pp_big_lab_sup` set `ADD_TYPE`= 1 where `ADD_TYPE` = 0;
update `pp_lab_lst_sup` set `ADD_TYPE`= 1 where `ADD_TYPE` = 0;";
                DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, sql, out ds);

            }
            catch (Exception err)
            {
                log(err.Message);
            }
        }

        /// <summary>
        /// 同步单个表
        /// </summary>
        /// <param name="tablename"></param>
        /// <param name="customercd"></param>
        /// <param name=""></param>
        private void SyncBaseData(string tablename, string customercd, DateTime startdate)
        {
            try
            {
                log($"同步{tablename}开始");
                var model = new SyncBusinessModel();
                model.CustomerCode = customercd;
                model.TenantId = SysConfig.TenantId; 
                var startDate = startdate;
                using (var db = DbHelperMySql.GetSqlSugarDb())
                {
                    startDate = db.Queryable<pp_lab_lst_sup>().Where(x => x.ADD_TYPE == 0
                    &&x.CUSTOMERCODE==customercd).Any() ? db.Queryable<pp_lab_lst_sup>().Where(x => x.ADD_TYPE == 0
                     && x.CUSTOMERCODE == customercd).Min(x=>x.CREATE_DT).Value: startdate;
                    log($"查询创建日期{startdate.ToString("MMddHHmm")}");
                    switch (tablename)
                    {
                        case "order_no":
                            model.OrderList = db.Queryable<order_no>()
                                .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd)
                                .OrderBy(p => p.ORDER_DATE)
                                .ToList();
                            if (model.OrderList.Count == 0) return;
                            break;
                        case "order_manage":
                            model.OrderManageList = db.Queryable<order_manage>()
                                .Where(b => b.ADD_TYPE == 0 && b.CUSTOMERCODE == customercd)
                                .OrderBy(p => p.DELIVERY_DATE)
                                .ToList();
                            if (model.OrderManageList.Count == 0) return;
                            break;
                        case "order_manage_list":
                            model.OrderManageDetailList = db.Queryable<order_manage_list, order_manage>((l, m) => new object[]{
                            JoinType.Left, l.ORDER_ID == m.ORDER_ID })
                                .Where((l, m) => l.ADD_TYPE == 0 && m.CUSTOMERCODE == customercd)
                                .OrderBy((l, m) => l.SCAN_TIME)
                                .Select((l, m) => l)
                                .ToList();
                            if (model.OrderManageDetailList.Count == 0) return;
                            break;
                        case "pp_big_lab_sup":
                            var smalls= db.Queryable<pp_big_lab_sup>()
                                .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd)
                                .OrderBy(p => p.CREATE_DT)
                                .ToList();
                            foreach (var item in smalls) {
                                item.BLACK_FLag = -1;
                            }
                            model.BigBarcodeList = smalls;
                            if (model.BigBarcodeList.Count == 0) return;
                            break;
                        case "pp_lab_lst_sup":
                            //大量数据
                            var bigs= db.Queryable<pp_lab_lst_sup>()
                                .Where(p => p.ADD_TYPE == 0 && p.CUSTOMERCODE == customercd && p.CREATE_DT >= startDate)
                                .OrderBy(p => p.CREATE_DT)
                                .ToList();
                            foreach (var item in bigs) {
                                item.State = -1;
                                }
                            model.SmallBarcodeList = bigs;
                            if (model.SmallBarcodeList.Count > 10000)
                            {
                                var icount = Math.Ceiling((decimal)model.SmallBarcodeList.Count / 5000);
                                var copymodel = DeepCopy.Clone(model);
                                copymodel.SmallBarcodeList = model.SmallBarcodeList.Take(5000).ToList();
                                #region task
                                //Task<List<SyncResultModel>> task = CreateTask(copymodel);
                                //task.Start();
                                //var result = task.Result;                                
                                //var synccount = SyncCount(result);
                                //for (var i = 1; i < icount; i++)
                                //{
                                //    copymodel.SmallBarcodeList = model.SmallBarcodeList.Skip(i * 5000).Take(5000).ToList();
                                //task = CreateTask(copymodel);
                                //task.Start();
                                //synccount += SyncCount(task.Result);
                                //}
                                //result.Where(p => p.TableName == tablename).FirstOrDefault().InsertCount = synccount;
                                //while (!task.IsCompleted)
                                //{
                                //    Console.WriteLine(task.Status);
                                //    Thread.Sleep(TimeSpan.FromSeconds(1));
                                //} 
                                #endregion
                                var result = TaskSync(copymodel);
                                var synccount = SyncCount(result);
                                for (var i = 1; i < icount; i++)
                                {
                                    copymodel.SmallBarcodeList = model.SmallBarcodeList.Skip(i * 5000).Take(5000).ToList();
                                    result = TaskSync(copymodel);
                                    synccount += SyncCount(result);
                                }
                                result.Where(p => p.TableName == tablename).FirstOrDefault().InsertCount = synccount;
                                return;
                            }
                            if (model.SmallBarcodeList.Count == 0) return;
                            break;
                    }
                }

                var url = SysConfig.SyncBusinessApiUrl;
                var reqjson = JsonConvert.SerializeObject(model);
                var responseStr = HttpHelper.WebRequestApi(url, reqjson, "POST");
                var syncResultList = JsonConvert.DeserializeObject<List<SyncResultModel>>(responseStr);

                DataSet ds = null;
                if (tablename != "order_manage_list")
                {
                    string sql = @"update " + tablename + $" set `ADD_TYPE`= 1 where `ADD_TYPE` = 0 and `CUSTOMERCODE`='{customercd}' ;";
                    DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, sql, out ds);
                }
                else
                {
                    string sql = @"update " + tablename + $" set `ADD_TYPE`= 1 where `ADD_TYPE` = 0 ;";
                    DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, sql, out ds);
                }
                log($"同步{tablename}成功{responseStr}");
            }
            catch (Exception ex)
            {
                log($"上传数据{tablename}失败" + ex.Message);
                throw;
            }
        }
        private void log(string str)
        {
            Console.WriteLine(str);
            LogHelper.CreateLoger().Error(str);
        }
        /// <summary>
        /// 返回执行统计结果
        /// </summary>
        /// <param name="syncResults"></param>
        /// <returns></returns>
        public int SyncCount(List<SyncResultModel> syncResults)
        {
            int i = 0;
            foreach (var item in syncResults)
            {
                i += (int)item.InsertCount;
            }
            return i;
        }
        public Task<List<SyncResultModel>> CreateTask(SyncBusinessModel model)
        {
            return new Task<List<SyncResultModel>>(() => TaskSync(model));
        }
        /// <summary>
        /// 同步方法
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public List<SyncResultModel> TaskSync(SyncBusinessModel model)
        {
            var url = SysConfig.SyncBusinessApiUrl;
            var reqjson = JsonConvert.SerializeObject(model);
            var responseStr = HttpHelper.WebRequestApi(url, reqjson, "POST");
            var syncResultList = JsonConvert.DeserializeObject<List<SyncResultModel>>(responseStr);
            return syncResultList;
        }
    }
}
